#include "bsp_ldr.h"
// #define BSP_LDR_DEBUG_LOG_OPEN // 开启调试信息

#define BSP_LDR_LOG "[bsp_ldr]"

static adc_channel_t g_ldr_adc_channel = 0; // LDR_ADC channel

static adc_scan_config_t g_ldr_adc_config = {
    .type = 0,
    .freq = 1,
};

static uint32_t g_ldr_scan_result_mv; // LDR ADC scan result in mV

// LDR ADC scan result callback
void __adc_scan_result_callback(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next)
{
    (void)next;

    uint32_t buffer_sum = 0, buffer_count = 0;

    for (uint32_t i = 0; i < length; i++)
    {
        if (ch == g_ldr_adc_channel && buffer[i] != 0)
        {
#ifdef BSP_LDR_DEBUG_LOG_OPEN
            osal_printk("%s channel: %d, voltage: %dmv\n", BSP_LDR_LOG, ch, buffer[i]);
#endif // BSP_LDR_DEBUG_LOG_OPEN

            if ((int32_t)buffer[i] >= 0)
            {
                buffer_sum += (int32_t)buffer[i];
                buffer_count++;
            }
        }
    }

#ifdef BSP_LDR_DEBUG_LOG_OPEN
    osal_printk("%s buffer_sum: %dmv, buffer_count: %d\n", BSP_LDR_LOG, buffer_sum, buffer_count);
#endif // BSP_LDR_DEBUG_LOG_OPEN

    if (buffer_count > 0)
    {
        g_ldr_scan_result_mv = buffer_sum / buffer_count; // 取电压平均值
    }
    else
    {
        g_ldr_scan_result_mv = 0;
    }
}

/**
 * @brief  初始化光敏电阻设备。
 * @param  [in] chnnel 光敏电阻设备使用的ADC通道， 参考 @ref adc_channel_t 。
 * @retval ERRCODE_SUCC 成功。
 * @retval Other        失败，参考 @ref errcode_t 。
 */
errcode_t bsp_ldr_init(adc_channel_t chnnel)
{
    errcode_t ret;

    // 保存引脚
    g_ldr_adc_channel = chnnel;

    // 初始化ADC
    ret = uapi_adc_init(ADC_CLOCK_500KHZ);
    if (ret != ERRCODE_SUCC)
    {
#ifdef BSP_LDR_DEBUG_LOG_OPEN
        osal_printk("%s uapi_adc_init failed, ret = %d\n", BSP_LDR_LOG, ret);
#endif // BSP_LDR_DEBUG_LOG_OPEN

        return ret;
    }

    // 启动ADC
    uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, true);
    if (ret != ERRCODE_SUCC)
    {
#ifdef BSP_LDR_DEBUG_LOG_OPEN
        osal_printk("%s uapi_adc_power_en failed, ret = %d\n", BSP_LDR_LOG, ret);
#endif // BSP_LDR_DEBUG_LOG_OPEN

        return ret;
    }

    return ERRCODE_SUCC;
}

/**
 * @brief  获取光敏电阻器获取的电压值。
 * @param  [out] value 获取到的光敏电阻器电压值，单位为mv。
 * @retval ERRCODE_SUCC 成功。
 * @retval Other        失败，参考 @ref errcode_t 。
 */
errcode_t bsp_ldr_get_value(uint32_t *value)
{
    if (value == NULL)
    {
#ifdef BSP_LDR_DEBUG_LOG_OPEN
        osal_printk("%s bsp_ldr_get_value invalid param\n", BSP_LDR_LOG);
#endif // BSP_LDR_DEBUG_LOG_OPEN

        return ERRCODE_INVALID_PARAM;
    }
    
    // 启动ADC自动扫描
    errcode_t ret = uapi_adc_auto_scan_ch_enable(g_ldr_adc_channel, g_ldr_adc_config, __adc_scan_result_callback);
    if (ret != ERRCODE_SUCC)
    {
#ifdef BSP_LDR_DEBUG_LOG_OPEN
        osal_printk("%s uapi_adc_auto_scan_ch_enable failed, ret = %d\n", BSP_LDR_LOG, ret);
#endif // BSP_LDR_DEBUG_LOG_OPEN

        return ret;
    }

    osal_msleep(10);
    // 停止ADC自动扫描
    ret = uapi_adc_auto_scan_ch_disable(g_ldr_adc_channel);
    if (ret != ERRCODE_SUCC)
    {
#ifdef BSP_LDR_DEBUG_LOG_OPEN
        osal_printk("%s uapi_adc_auto_scan_ch_disable failed, ret = %d\n", BSP_LDR_LOG, ret);
#endif // BSP_LDR_DEBUG_LOG_OPEN

        return ret;
    }


    *value = g_ldr_scan_result_mv;

    return ERRCODE_SUCC;
}
